﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using Microsoft.Dynamics.BusinessConnectorNet;

namespace PJ.Data
{
    /// <summary>
    /// Dynamics AX server implementation of <see cref="IItemProvider"> persistence interface. 
    /// </summary>
    /// <typeparam name="TIItemData">Item data interface type</typeparam>
    /// <typeparam name="TItemData">Item data concrete class type</typeparam>
    public abstract class ItemAXProvider<TIItemData> : EntityAXProvider<TIItemData>, IItemProvider<TIItemData>
        where TIItemData : class, IItemData
    {
        protected ItemAXProvider(IItemCache<TIItemData> cache) : base(cache)
        {

        }
        protected override void CopyFromContainer(AxaptaContainer container, TIItemData data)
        {
            base.CopyFromContainer(container, data);
            if (container.Count < 2)
                throw new ArgumentOutOfRangeException("container", container.Count, "should have at least 2 items");
            data.Name = ((string)container.get_Item(2)).Trim();
        }

        IItemData IItemProvider.GetByName(string name)
        {
            return GetByName(name);
        }

        IItemData IItemProvider.CachedGetByName(string name)
        {
            return CachedGetByName(name);
        }


        IItemData IItemProvider.FindByName(string name)
        {
            return FindByName(name);
        }

        IItemData IItemProvider.CachedFindByName(string name)
        {
            return CachedFindByName(name);
        }


        public virtual TIItemData GetByName(string name)
        {
            TIItemData t = FindByName(name);
            if (t == null)
                throw new Data.DataNotFoundException();
            else
                return t;
        }

        public TIItemData CachedGetByName(string name)
        {
            return GetByName(name);
        }

        public virtual TIItemData FindByName(string name)
        {
            if (string.IsNullOrEmpty(name))
                throw new ArgumentNullException("name");
            using (AxaptaContainer container = 
                (AxaptaContainer)CallAXStaticMethod("FindByName", name))
            {
                if (container.Count != 0)
                {
                    return CreateNewItem(container);
                }
                else
                    return null;
            }

        }
        public TIItemData CachedFindByName(string name)
        {
            return FindByName(name);
        }

        public virtual IEnumerable<string> Search(string searchText)
        {
            if (string.IsNullOrEmpty(searchText))
                throw new ArgumentNullException("searchText");
            using (AxaptaContainer container = (AxaptaContainer)CallAXStaticMethod("Search", searchText))
            {
                if (container.Count != 0)
                {
                    List<string> list = new List<string>();
                    foreach (string globalId in container)
                        list.Add(globalId);
                    return list;
                }
                else
                    return null;
            }

        }

        public IEnumerable<string> CachedSearch(string searchText)
        {
            return Search(searchText);
        }

    }
}
